package cn.tedu.submarine;

import javax.swing.JFrame;
import javax.swing.JPanel;
import java.awt.*;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.*;

/**
 * 游戏窗口
 */
public class World extends JPanel {
    public static final int WIDTH = 1080;//窗口宽
    public static final int HEIGHT = 850;//窗口高

    public static final int RUNNING = 0;//游戏运行状态
    public static final int PAUSE = 1;//游戏暂停状态
    public static final int GAME_OVER = 2;//游戏结束状态
    private int state = RUNNING;//默认游戏运行
    public static int levelNumber = 1; //关卡序号
    public static int magnification = 40; //放大倍数（Boss血条）

    public static final int ULT_FALSE = 0;//大招关
    public static final int ULT_TRUE = 1;//大招开
    private int ultState = ULT_FALSE;//大招释放（默认关）
    private int ultIndex = 0;//大招下标
    private int ultTime = 0;//大招时间控制
    private boolean shieldWitch = false;//护盾魔女状态
    private boolean shieldState = false;//护盾状态
    private int shieldIndex = 0;//护盾图片下标
    private int shieldTime = 0;//护盾绘制间隔


    private Battleship[] ship = {new Battleship(110,86,250, Battleship.ONESHIP),
            new Battleship(93,85,290, Battleship.TWOSHIP)}; //战舰生成
    private Boss boss = new Boss(); //Boss生成
    private SeaObject[] submarines = {}; //潜艇数组
    private Bomb[] bombs = {}; //深水炸弹数组
    private Mine[] mines = {}; //水雷数组
    private Coin[] coins = {}; //金币数组
    private BossBomb[] bossBombs = {}; //金币数组


    /**
     * 潜艇对象生成
     *
     * @return
     */
    public SeaObject nextSubmarine() {
        Random rands = new Random();
        int type = rands.nextInt(40);
        if (type < 16) {
            return new ObserveSubmarine();//生成侦查潜艇
        } else if (type < 25) {
            return new TorpedoSubmarine();//生成鱼雷潜艇
        } else if (type < 35) {
            return new MineSubmarine();//生成水雷潜艇
        } else {
            return new RewardSubmarine();//生成多倍炸弹潜艇
        }
    }

    /**
     * 潜艇入场
     */
    private int sei = 0;

    public void submarineEnterAction() {
        sei++;
        if (sei % 40 == 0) {
            SeaObject obj = nextSubmarine();
            submarines = Arrays.copyOf(submarines, submarines.length + 1);
            submarines[submarines.length - 1] = obj;
        }
    }

    /**
     * 水雷入场
     */
    private int mei = 0;

    public void mineEnterAction() {
        mei++;
        if (mei % 100 == 0) {
            for (int i = 0; i < submarines.length; i++) {
                if (submarines[i] instanceof MineSubmarine) {
                    MineSubmarine m = (MineSubmarine) submarines[i];
                    Mine obj = m.shootMine();
                    mines = Arrays.copyOf(mines, mines.length + 1);
                    mines[mines.length - 1] = obj;
                }
            }
        }
    }

    /**
     * boss子弹入场
     */
    private int bbIndex = 0;
    private int fire;
    Random rand = new Random();

    public void bossBombEnterAction() {
        if (boss.isLive()) {
            bbIndex++;
            if (bbIndex % 100 == 0) {
                fire = levelNumber;
                if (fire >= 2) {
                    fire = 2;
                    BossBomb[] obj = boss.shootBossBo(rand.nextInt(fire) + 1);
                    bossBombs = Arrays.copyOf(bossBombs, bossBombs.length + obj.length);
                    System.arraycopy(obj, 0, bossBombs, bossBombs.length - obj.length, obj.length);
                    Images.bbsound.play();//boss子弹音效
                } else {
                    BossBomb[] obj = boss.shootBossBo(rand.nextInt(fire) + 1);
                    bossBombs = Arrays.copyOf(bossBombs, bossBombs.length + obj.length);
                    System.arraycopy(obj, 0, bossBombs, bossBombs.length - obj.length, obj.length);
                    Images.bbsound.play();//boss子弹音效
                }
            }
        }
    }

    /**
     * 金币入场
     */
    public void CoinEnter(SeaObject sea, Battleship ship) {
        Coin c = new Coin(sea.getX(), sea.getY(), ship.getMarker());
        coins = Arrays.copyOf(coins, coins.length + 1);
        coins[coins.length - 1] = c;
    }


    /**
     * BOSS入场
     */
    public void bossEmterAction() {
        boss.BossCounter();
    }


    /**
     * 海洋对象移动
     */
    public void moveAction() {
        for (SeaObject obj : submarines) {//潜艇的移动
            if (obj.isLive()) {
                obj.move();
            }
        }
        for (Mine m : mines) {
            m.move();
        }
        for (Bomb b : bombs) {
            b.move();
        }
        for (BossBomb bb : bossBombs) {
            bb.move();
        }
        for (Coin c : coins) {
            if (c.getMarker() == 0) {
                c.remove(ship[0]);
            } else if (c.getMarker() == 1) {
                c.remove(ship[1]);
            }
        }
        if (boss.isLive()) {
            boss.move();
        }

    }

    /**
     * 海洋对象（越界、碰撞）删除
     */
    public void outBoundsAction() {
        for (int i = 0; i < submarines.length; i++) {
            if (submarines[i].isOutBounds() || submarines[i].isRemove()) {
                submarines[i] = submarines[submarines.length - 1];
                submarines = Arrays.copyOf(submarines, submarines.length - 1);
            }
        }

        for (int i = 0; i < mines.length; i++) {
            if (mines[i].isOutBounds() || mines[i].isRemove()) {
                mines[i] = mines[mines.length - 1];
                mines = Arrays.copyOf(mines, mines.length - 1);
            }
        }
        for (int i = 0; i < bombs.length; i++) {
            if (bombs[i].isOutBounds() || bombs[i].isRemove()) {
                bombs[i] = bombs[bombs.length - 1];
                bombs = Arrays.copyOf(bombs, bombs.length - 1);
            }
        }
        for (int i = 0; i < coins.length; i++) {
            if (coins[i].isRemove()) {
                coins[i] = coins[coins.length - 1];
                coins = Arrays.copyOf(coins, coins.length - 1);
            }
        }
        for (int i = 0; i < bossBombs.length; i++) {
            if (bossBombs[i].isRemove() || bossBombs[i].isOutBounds()) {
                bossBombs[i] = bossBombs[bossBombs.length - 1];
                bossBombs = Arrays.copyOf(bossBombs, bossBombs.length - 1);
            }
        }
        if (boss.isRemove()) {
            boss = new Boss();
        }
    }

    /**
     * 炸弹潜艇碰撞(加分，加命)
     */
    private int score = 0;

    public void bombBangAction() {
        for (Bomb b : bombs) {//遍历炸弹
            for (SeaObject sea : submarines) {//遍历潜艇
                if (b.isLive() && sea.isLive() && sea.isHit(b)) {
                    sea.subtractLife();//潜艇扣血
                    if (sea.getLife() <= 0) {
                        sea.goDead(); //潜艇死亡状态
                        sea.setLocation();//改动爆炸坐标
                        Images.boom.play();//爆炸音效
                        if (b.getMarker() == ship[0].getMarker()) {//判断炸弹潜艇编号是否相同
                            CoinEnter(sea, ship[0]);//战舰1获取金币
                        } else if (b.getMarker() == ship[1].getMarker()) {//判断炸弹潜艇编号是否相同
                            CoinEnter(sea, ship[1]);//战舰2获取金币
                        }
                    }
                    b.goRemove(); //炸弹删除
                    if (sea instanceof RewardSubmarine) {//获取多倍子弹
                        if (b.getMarker() == 0) {
                            ship[0].changeFireTwo();//战舰1获取
                        } else if (b.getMarker() == 1) {
                            ship[1].changeFireTwo();//战舰2获取
                        }
                    }
                    if (sea instanceof EnemyScore) {//获取分数
                        EnemyScore es = (EnemyScore) sea;
                        score += es.getScore();
                    }
                    if (sea instanceof EnemyLife) {//获取生命
                        EnemyLife el = (EnemyLife) sea;
                        int num = el.shipGetLife();
                        if (b.getMarker() == 0 && ship[0].getLife() < Battleship.LIFE) {
                            ship[0].addLife(num);//战舰1获取
                        } else if (b.getMarker() == 1 && ship[1].getLife() < Battleship.LIFE) {
                            ship[1].addLife(num);//战舰2获取
                        }
                    }
                }
            }
        }
    }

    /**
     * 金币战舰碰撞（加金币）
     */
    public void coinBangAction() {
        for (int i = 0; i < coins.length; i++) {
            Coin c = coins[i];
            int num = c.getCoin();
            if (c.getMarker() == 0 && c.isLive() && ship[0].isLive() && c.isHit(ship[0])) {
                coins[i].goRemove();
                ship[0].addCoin(num);
                Images.coinsound.stop();//捡金币音效关闭
                Images.coinsound.play();//开启
            } else if (c.getMarker() == 1 && c.isLive() && ship[1].isLive() && c.isHit(ship[1])) {
                coins[i].goRemove();
                ship[1].addCoin(num);
                Images.coinsound.stop();//捡金币音效关闭
                Images.coinsound.play();//开启
            }
        }
    }

    /**
     * 水雷战舰碰撞
     */
    public void mineBangAction() {
        for (Mine m : mines) {
            if (m.isLive() && ship[0].isLive() && m.isHit(ship[0])) {
                m.goRemove();
                if (shieldState==false) {//判断是否有护盾
                    ship[0].subtractLife();
                    if (ship[0].getLife() <= 0) {
                        ship[0].goDead();
                    }
                }
            }
            if (m.isLive() && ship[1].isLive() && m.isHit(ship[1])) {
                m.goRemove();
                if (shieldState==false) {
                    ship[1].subtractLife();
                    if (ship[1].getLife() <= 0) {
                        ship[1].goDead();
                    }
                }
            }
        }
    }

    /**
     * boss子弹战舰碰撞
     */
    public void bossBombsBangAction() {
        for (BossBomb bb : bossBombs) {
            if (bb.isLive() && ship[0].isLive() && bb.isHit(ship[0])) {
                bb.goRemove();
                if (shieldState==false) {//判断是否有护盾
                    ship[0].subtractLife(bb.getFire());
                    if (ship[0].getLife() <= 0) {
                        ship[0].goDead();
                    }
                }
            }
            if (bb.isLive() && ship[1].isLive() && bb.isHit(ship[1])) {
                bb.goRemove();
                if (shieldState==false) {//判断是否有护盾
                    ship[1].subtractLife(bb.getFire());
                    if (ship[1].getLife() <= 0) {
                        ship[1].goDead();
                    }
                }
            }
        }
    }

    /**
     * 炸弹与Boss碰撞
     */
    public void bossBangAction() {
        for (Bomb b : bombs) {
            if (b.isLive() && boss.isLive() && b.isHit(boss)) {
                b.goRemove();
                if (boss.getLife() <= 0) {
                    boss.goDead();
                    levelNumber++;
                } else {
                    boss.subtractLife();
                }
            }
        }
    }


    /**
     * 一键清屏方法
     */
    public void cls(Battleship ship) {
        ship.setCoinNumber();
        for (SeaObject s : submarines) {
            if (s.isLive()) {
                CoinEnter(s, ship);
                s.goDead();
                if (s instanceof EnemyScore) {
                    EnemyScore es = (EnemyScore) s;
                    score += es.getScore();
                }
                if (s instanceof EnemyLife) {
                    EnemyLife el = (EnemyLife) s;
                    int num = el.shipGetLife();
                    ship.addLife(num);
                }
            }
        }
        for (Mine m : mines) {
            if (m.isLive()) {
                m.goRemove();
            }
        }
    }

    /**
     * 多倍子弹时间
     */
    private int fireIndex = 0;

    public void fireAction() {
        fireIndex++;
        for (int i = 0; i < ship.length; i++) {
            if (ship[i].getFire() == Battleship.FIRETWO) {//如果战舰火力为3
                if (fireIndex % 600 == 0) {
                    ship[i].changeFireOne();//战舰火力改为1
                }
            }
        }
    }

    /**
     * 判断游戏结束
     */
    public void chevkGameOverAction() {
        if (ship[0].isRemove() && ship[1].isRemove()) {
            state = GAME_OVER;
            Images.bgm.stop();//暂停bgm
            Images.gameoversound.play();//播放gameover
        }
    }

    /**
     * 程序的执行
     */
    public void action() {

        //战舰1活着执行
        //战舰1移动
        MouseAdapter m1 = new MouseAdapter() {
            public void mouseMoved(MouseEvent e) {
                if (state == RUNNING) {//游戏运行状态
                    if (ship[1].isLive()) {
                        int x = e.getX();//获取鼠标坐标
                        ship[1].toMove(x);
                    }
                }
            }
        };
        //战舰1放炸弹
        MouseAdapter m2 = new MouseAdapter() {
            public void mousePressed(MouseEvent e) {
                if (state == RUNNING) {//游戏运行状态
                    if (ship[1].isLive()) {
                        if (e.getButton() == 1) {
                            Bomb[] obj = ship[1].shootBomb();
                            bombs = Arrays.copyOf(bombs, bombs.length + obj.length);
                            System.arraycopy(obj, 0, bombs, bombs.length - obj.length, obj.length);
                            Images.bombsound.play();//战舰子弹音效
                        } else if (e.getButton() == 3) {
                            if (ship[1].getCoinNumber() >= 30) {
                                ultState = ULT_TRUE;
                            }
                        }
                    }
                }
            }
        };
        this.addMouseMotionListener(m1);
        this.addMouseListener(m1);
        this.addMouseMotionListener(m2);
        this.addMouseListener(m2);

        //战舰2活着执行
        KeyAdapter k1 = new KeyAdapter() {
            public void keyPressed(KeyEvent e) {
                if (ship[0].isLive()) {
                    if (state == RUNNING) {
                        if (e.getKeyCode() == KeyEvent.VK_LEFT) {//战舰向左
                            ship[0].moveleft();
                        }
                        if (e.getKeyCode() == KeyEvent.VK_RIGHT) {//战舰向右
                            ship[0].moveRight();
                        }
                    }
                }
            }
        };
        KeyAdapter k = new KeyAdapter() {
            public void keyReleased(KeyEvent e) {
                if (ship[0].isLive()) {
                    if (e.getKeyCode() == KeyEvent.VK_P) {//游戏暂停
                        if (state == RUNNING) {
                            state = PAUSE;
                            Images.bgm.stop();
                        } else if (state == PAUSE) {
                            state = RUNNING;
                            Images.bgm.loop();
                        }
                    }
                    if (state == RUNNING) {
                        if (e.getKeyCode() == KeyEvent.VK_SPACE) {//战舰2放炸弹
                            Bomb[] obj = ship[0].shootBomb();
                            bombs = Arrays.copyOf(bombs, bombs.length + obj.length);
                            System.arraycopy(obj, 0, bombs, bombs.length - obj.length, obj.length);
                            Images.bombsound.play();//战舰子弹音效
                        }
                    }
                    if (state == RUNNING) {
                        if (ship[0].getCoinNumber() >= 30) {
                            if (e.getKeyCode() == KeyEvent.VK_I) { //护盾
                                ship[0].setCoinNumber();
                                shieldWitch = true;
                            }
                        }
                    }
                }
            }
        };
        this.addKeyListener(k);
        this.addKeyListener(k1);

        Timer timer = new Timer();
        int interval = 10;
        timer.schedule(new TimerTask() {
            public void run() {
                if (state == RUNNING) {
                    submarineEnterAction();//潜艇入场
                    mineEnterAction();//水雷入场
                    bossEmterAction();//Boss入场
                    bossBombEnterAction();//Boss子弹入场
                    bombBangAction();//深水炸弹与潜艇碰撞
                    mineBangAction();//水雷与战舰碰撞
                    bossBangAction();//Boss与深水炸弹碰撞
                    bossBombsBangAction();//战舰与Boss子弹碰撞
                    outBoundsAction();//对象删除
                    coinBangAction();//金币与战舰碰撞
                    chevkGameOverAction();//游戏结束
                    fireAction();
                    moveAction();
                    repaint();
                }
            }
        }, interval, interval);
    }

    /**
     * 画笔
     *
     * @param g
     */
    public void paint(Graphics g) {

        if (levelNumber<Images.sea.length) {
            Images.sea[levelNumber-1].paintIcon(null, g, 0, 0); //画海洋
        }else {
            Images.sea[Images.sea.length-1].paintIcon(null, g, 0, 0); //画海洋
        }
        for (int i = 0; i < ship.length; i++) {
            ship[i].paintImage(g); //画战舰
            if (ship[i].isLive()) {//画战舰血条
                g.setColor(Color.GRAY);
                g.fillRect(ship[i].getX(), ship[i].getY() - 15, 90, 8);
                g.setColor(Color.GREEN);
                g.fillRect(ship[i].getX(), ship[i].getY() - 15, 90 * ship[i].getLife() / Battleship.LIFE, 8);
            }
        }
        if (shieldWitch == true){//画护盾魔女
            Images.shieldwitch[shieldIndex].paintIcon(null,g,ship[0].getX()+ship[0].getWidth()/8,ship[0].getY()-110);
            shieldTime++;
            if (shieldTime%10==0){
                shieldIndex++;
            }
            if (shieldIndex==25){
                shieldIndex = 0;
                shieldTime = 0;
                shieldWitch = false;
                shieldState = true;

            }
        }

        if (shieldState == true){//画护盾
            for (Battleship b : ship) {
                if (b.isLive()) {
                    Images.shield[shieldIndex].paintIcon(null,g,b.getX(),b.getY()-50);
                }
            }
            shieldTime++;
            if (shieldTime%10==0){
                shieldIndex++;
            }
            if (shieldIndex==7){
                shieldIndex = 0;
            }
            if (shieldTime==600){//护盾持续时间
                shieldTime = 0;
                shieldState = false;
            }
        }

        boss.paintImage(g); //画Boss
        if (boss.isLive()) { //Boss血条
            Images.bosshp.paintIcon(null,g,240,50);//boss血条框
            g.setColor(Color.RED);
            g.fillRect(301, 88, 475 * boss.getLife() / levelNumber / magnification, 31);
        }
        Images.coin[1].paintIcon(null, g, 20, 45); //金币图标
        Images.coin[1].paintIcon(null, g, 20, 85); //金币图标
        for (Coin c : coins) {
            c.paintImage(g);
        }
        for (SeaObject sea : submarines) {
            sea.paintImage(g); //画潜艇
            if (sea.isLive()) {
                g.setColor(Color.GRAY); //潜艇血条
                g.fillRect(sea.getX() + 10, sea.getY() - 7, 60, 5);
                g.setColor(Color.RED);
                g.fillRect(sea.getX() + 10, sea.getY() - 7, 60 * sea.getLife() / levelNumber, 5);
            }
        }
        for (Bomb bomb : bombs) {
            bomb.paintImage(g); //画炸弹
        }
        for (Mine mine : mines) {
            mine.paintImage(g); //画水雷
        }
        for (BossBomb bb : bossBombs) {//画boss子弹
            bb.paintImage(g);
        }

        if (ultState==ULT_TRUE) {//画大招
            ultTime++;
            Images.ult[ultIndex].paintIcon(null, g, 50, 100);
            if (ultTime % 10 == 0) {
                ultIndex++;
            }
            if (ultIndex == Images.ult.length) {
                cls(ship[1]);
                ultState = ULT_FALSE;
                ultIndex = 0;
            }
        }

        //字体
        Font difficulty = new Font("幼圆", Font.BOLD, 30);
        g.setFont(difficulty);
        g.setColor(Color.red);
        g.drawString("第" + levelNumber+"关", 460, 40);



        //字体
        Font difficulty1 = new Font("幼圆", Font.BOLD, 20);
        g.setFont(difficulty1);
        g.setColor(Color.WHITE);

        g.drawString("1x" + ship[0].getCoinNumber(), 60, 70);
        g.drawString("2x" + ship[1].getCoinNumber(), 60, 110);
        g.drawString("SCORE:" + score, 20, 20);
        if (state == GAME_OVER) {//画gameover
            Images.gameover.paintIcon(null, g, 0, 0);
        }

    }

    public static void main(String[] args) {
        JFrame frame = new JFrame(); //3
        World world = new World(); //会创建上面的那一堆对象
        world.setFocusable(true);
        frame.add(world);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(WIDTH + 16, HEIGHT + 39);
        frame.setLocationRelativeTo(null);
        frame.setResizable(true);
        frame.setVisible(true); //自动调用paint()方法
        world.action();
        Images.bgm.loop();//背景音乐
    }
}
